//
//  String+URL.swift
//  TTCOM
//
//  Created by Toj on 1/17/23.
//

import Foundation

/** URL
 * parameters: [String: String]
 * queries: [String: String]
 * queryString: smartcard=12345678910&name=tao
 */
public extension String {
    
    /**
     * 返回 url字符串 后面 query参数
     * e.g.: http://startimestv.com?card=12345&name=tao
     * result: ["card":"12345", "name":"tao"]
     */
    var url_queryParameters: [String: String]? {
        let queryParameters = URL(string: self)?.cm_queryParameters
        return queryParameters
    }
    
    /** 同上, 利用CM.absoluteTimes 明显用URL取值快点
     * 返回 url字符串 后面 query参数
     * e.g.: http://startimestv.com?card=12345&name=tao
     * result: ["card":"12345", "name":"tao"]
     */
    var url_queries: [String: String]? {
        let queryString = st_subsring(from: "?")
        let queries = String(queryString).to_queries
        return queries
    }
    
    /**
     * 返回 url字符串 host
     * e.g.: http://qa.startimestv.com/hybrid?card=123&name=tao
     * result: qa.startimestv.com
     */
    var url_host: String {
        let url = URL(string: self)
        return url?.host ?? ""
    }
    
    /**
     * 返回 url字符串 path
     * e.g.: http://startimestv.com/hybrid/dvb/bind?card=1234
     * result: /hybrid/dvb/bind
     */
    var url_path: String {
        let url = URL(string: self)
        return url?.path ?? ""
    }
    
    /**
     * 返回 url字符串 全路径: 包括域名 + path
     * e.g.: http://startimestv.com/hybrid?card=12345
     * result: http://startimestv.com/hybrid
     */
    var url_fullPath: String {
        let full = split(separator: "?").first ?? ""
        return String(full)
    }
    
    /**
     在现有url字符串后面拼接 参数(字符串)
     
     -  url后面:
     -      有参: 追加新参数.
     -      无参: 拼接新参数.
     
     - parameter string: 参数
     
     ```
     let string = "name=tao&age=11"
     "http://startimestv.com?card=12345".url_appendQueryString(string)
     result: "http://startimestv.com?card=12345&name=tao&age=11"
     ```
     */
    mutating func url_appending(queried string: String) {
        self = url_append(queried: string)
    }
    
    /**
     url字符串后面拼接 参数(字符串)
     
     -  url后面:
     -      有参: 追加新参数.
     -      无参: 拼接新参数.
     
     - parameter string: 参数
     - returns: 带有参数的url
     
     ```
     let string = "name=tao&age=11"
     "http://startimestv.com?card=12345".url_appendQueryString(string)
     result: "http://startimestv.com?card=12345&name=tao&age=11"
     ```
     */
    func url_append(queried string: String) -> String {
        // 临时URL为了获取参数
        let tmpURL = "https://moc?\(string)"
        // 新参数字典
        let parameters = tmpURL.url_queryParameters ?? [:]
        // 新参数字典 拼接到url后面
        let urlString = url_append(queried: parameters)
        return urlString
    }
    
    /**
     在现有url字符串 后面拼接 参数(字典)
     
     -  url后面:
     -      有参: 追加新参数.
     -      无参: 拼接新参数.
     
     - parameter parameters: 参数(字典)
     ```
     let parameters = ["age":"11""]
     "http://startimestv.com?card=12345".url_append(queried: parameters)
     result: "http://startimestv.com?card=12345&age=11"
     ```
     */
    mutating func url_appending(queried parameters: [String: String]) {
        self = url_append(queried: parameters)
    }
    
    /**
     url字符串后面拼接 参数(字典)
     
     -  url后面:
     -      有参: 追加新参数.
     -      无参: 拼接新参数.
     
     - parameter parameters: 参数(字典)
     - returns: 带有参数的url
     ```
     let parameters = ["age":"11""]
     "http://startimestv.com?card=12345".url_append(queried: parameters)
     result: "http://startimestv.com?card=12345&age=11"
     ```
     */
    func url_append(queried parameters: [String: String]) -> String {
        guard !parameters.isEmpty else { return self }

        var params = url_queryParameters ?? [:]
        params += parameters
        
        let urlString = url_fullPath.url_append(queries: params)
        return urlString
    }
    
    /**
     全路径url 拼接 参数(字典)
     - parameter parameters: 参数(字典)
     - returns: 带有参数的url
     
     - NOTE: url后面不能有参数:
     
     ```
     let parameters = ["card": "1234", "age":"11", "name":"tao"]
     "http://startimestv.com".url_append(query: parameters)
     result: "http://startimestv.com?card=1234&name=tao&age=11"
     ```
     */
    func url_append(queries parameters: [String: String]) -> String {
        guard !isEmpty, !parameters.isEmpty else { return self }
       
        let queryString = parameters.to_queryString
        guard !queryString.isEmpty else { return self }
        
        var urlString = self
        if !urlString.hasSuffix("?") {
            urlString = urlString + "?"
        }
        let result = urlString + queryString
        return result
    }
}

/** query */
public extension String {
    
    // queryString 特殊字符编码
    var url_queryEncoding: String {
        if isEmpty { return self }
        let characters = ":#[]@!$&'()*+,.;=/?"
        var urlQueryAllowed = CharacterSet.urlQueryAllowed
        urlQueryAllowed.remove(charactersIn: characters)
        let escaped = addingPercentEncoding(withAllowedCharacters: urlQueryAllowed) ?? self
        return escaped
    }
    
    /**
     * queries to dictionary
     * e.g.: card=1234&name=tao&age=11
     * retsult: ["card": "1234", "age":"11", "name":"tao"]
     */
    var to_queries: [String: String] {
        var parameters = [String: String]()
        if isEmpty { return parameters }
        
        let queries = split(separator: Character("&"))
        queries.forEach { query in
            let string = query.removingPercentEncoding ?? ""
            
            let keyValue = string.st_split(by: "=")
            guard !keyValue.key.isEmpty else { return }
            
            let key = keyValue.key
            let value = keyValue.value
            
            parameters[key] = value
        }
        
        return parameters
    }
}
